import { Shortcut, ThemeMode } from '@shared/types.d';
import ElectronStore from 'electron-store';

import { eventBus } from './eventbus';
import { log } from './logger';

/**
 * 配置项的键名枚举
 */
enum ConfigKey {
  THEME = 'theme',
  AUTO_START = 'autoStart', // 开机启动
  START_TO_TRAY = 'startToTray', // 启动到托盘
  CLOSE_TO_TRAY = 'closeToTray', // 关闭时最小化到托盘
  LANGUAGE = 'language', // 界面语言
  AUTO_UPDATE = 'autoUpdate', // 自动检查更新
  BETA_UPDATES = 'betaUpdates', // 接收预发布版本
  MEMORY_LIMIT = 'memoryLimit', // 内存使用限制
  HARDWARE_ACCELERATION = 'hardwareAcceleration', // 硬件加速
  SHOW_TRAY_ICON = 'showTrayIcon', // 显示托盘图标
  SOUND_EFFECTS = 'soundEffects', // 音效
  SHORTCUTS = 'shortcuts',
  ALWAYS_ON_TOP = 'alwaysOnTop'
}

interface ConfigStore {
  theme: ThemeMode;
  autoStart: boolean; // 开机启动
  startToTray: boolean; // 启动到托盘
  closeToTray: boolean; // 关闭时最小化到托盘
  language: string; // 界面语言
  autoUpdate: boolean; // 自动检查更新
  betaUpdates: boolean; // 接收预发布版本
  memoryLimit: number; // 内存使用限制 (MB)
  hardwareAcceleration: boolean; // 硬件加速
  showTrayIcon: boolean; // 显示托盘图标
  soundEffects: boolean; // 音效
  shortcuts: Shortcut[];
  alwaysOnTop: boolean;
}

// ElectronStore 配置文件名常量
const STORE_NAME = 'app-config';

export class Config {
  private store: ElectronStore<ConfigStore>;

  constructor() {
    this.store = new ElectronStore<ConfigStore>({
      name: STORE_NAME, // 使用常量
      defaults: {
        theme: ThemeMode.auto,
        autoStart: false,
        startToTray: false,
        closeToTray: true,
        language: 'zh-CN',
        autoUpdate: true,
        betaUpdates: false,
        memoryLimit: 2048,
        hardwareAcceleration: true,
        showTrayIcon: true,
        soundEffects: true,
        shortcuts: [],
        alwaysOnTop: false
      },
      watch: true
    });
  }

  get<K extends keyof ConfigStore>(key: K): ConfigStore[K] {
    return (this.store.get as any)(key);
  }

  set<K extends keyof ConfigStore>(key: K, value: ConfigStore[K]): void {
    (this.store.set as any)(key, value);
  }

  getTheme(): ThemeMode {
    return this.get(ConfigKey.THEME);
  }

  setTheme(theme: ThemeMode): void {
    log.info(`Setting theme to: ${theme}`);
    const currentTheme = this.get(ConfigKey.THEME);
    if (currentTheme !== theme) {
      this.set(ConfigKey.THEME, theme);
      eventBus.emit('theme:changed', theme);
    }
  }

  // 常规设置相关方法
  getAutoStart(): boolean {
    return this.get(ConfigKey.AUTO_START);
  }

  setAutoStart(value: boolean): void {
    log.info(`Setting autoStart to: ${value}`);
    const currentValue = this.get(ConfigKey.AUTO_START);
    if (currentValue !== value) {
      this.set(ConfigKey.AUTO_START, value);
      eventBus.emit('autoStart:changed', value);
    }
  }

  getStartToTray(): boolean {
    return this.get(ConfigKey.START_TO_TRAY);
  }

  setStartToTray(value: boolean): void {
    log.info(`Setting startToTray to: ${value}`);
    const currentValue = this.get(ConfigKey.START_TO_TRAY);
    if (currentValue !== value) {
      this.set(ConfigKey.START_TO_TRAY, value);
      eventBus.emit('startToTray:changed', value);
    }
  }

  getCloseToTray(): boolean {
    return this.get(ConfigKey.CLOSE_TO_TRAY);
  }

  setCloseToTray(value: boolean): void {
    log.info(`Setting closeToTray to: ${value}`);
    const currentValue = this.get(ConfigKey.CLOSE_TO_TRAY);
    if (currentValue !== value) {
      this.set(ConfigKey.CLOSE_TO_TRAY, value);
      eventBus.emit('closeToTray:changed', value);
    }
  }

  getLanguage(): string {
    return this.get(ConfigKey.LANGUAGE);
  }

  setLanguage(value: string): void {
    log.info(`Setting language to: ${value}`);
    const currentValue = this.get(ConfigKey.LANGUAGE);
    if (currentValue !== value) {
      this.set(ConfigKey.LANGUAGE, value);
      eventBus.emit('language:changed', value);
    }
  }

  getAutoUpdate(): boolean {
    return this.get(ConfigKey.AUTO_UPDATE);
  }

  setAutoUpdate(value: boolean): void {
    log.info(`Setting autoUpdate to: ${value}`);
    const currentValue = this.get(ConfigKey.AUTO_UPDATE);
    if (currentValue !== value) {
      this.set(ConfigKey.AUTO_UPDATE, value);
      eventBus.emit('autoUpdate:changed', value);
    }
  }

  getBetaUpdates(): boolean {
    return this.get(ConfigKey.BETA_UPDATES);
  }

  setBetaUpdates(value: boolean): void {
    log.info(`Setting betaUpdates to: ${value}`);
    const currentValue = this.get(ConfigKey.BETA_UPDATES);
    if (currentValue !== value) {
      this.set(ConfigKey.BETA_UPDATES, value);
      eventBus.emit('betaUpdates:changed', value);
    }
  }

  getMemoryLimit(): number {
    return this.get(ConfigKey.MEMORY_LIMIT);
  }

  setMemoryLimit(value: number): void {
    log.info(`Setting memoryLimit to: ${value}`);
    const currentValue = this.get(ConfigKey.MEMORY_LIMIT);
    if (currentValue !== value) {
      this.set(ConfigKey.MEMORY_LIMIT, value);
      eventBus.emit('memoryLimit:changed', value);
    }
  }

  getHardwareAcceleration(): boolean {
    return this.get(ConfigKey.HARDWARE_ACCELERATION);
  }

  setHardwareAcceleration(value: boolean): void {
    log.info(`Setting hardwareAcceleration to: ${value}`);
    const currentValue = this.get(ConfigKey.HARDWARE_ACCELERATION);
    if (currentValue !== value) {
      this.set(ConfigKey.HARDWARE_ACCELERATION, value);
      eventBus.emit('hardwareAcceleration:changed', value);
    }
  }

  getShowTrayIcon(): boolean {
    return this.get(ConfigKey.SHOW_TRAY_ICON);
  }

  setShowTrayIcon(value: boolean): void {
    log.info(`Setting showTrayIcon to: ${value}`);
    const currentValue = this.get(ConfigKey.SHOW_TRAY_ICON);
    if (currentValue !== value) {
      this.set(ConfigKey.SHOW_TRAY_ICON, value);
      eventBus.emit('showTrayIcon:changed', value);
    }
  }

  getSoundEffects(): boolean {
    return this.get(ConfigKey.SOUND_EFFECTS);
  }

  setSoundEffects(value: boolean): void {
    log.info(`Setting soundEffects to: ${value}`);
    const currentValue = this.get(ConfigKey.SOUND_EFFECTS);
    if (currentValue !== value) {
      this.set(ConfigKey.SOUND_EFFECTS, value);
      eventBus.emit('soundEffects:changed', value);
    }
  }

  // 批量更新常规设置
  updateGeneralSettings(
    settings: Partial<{
      autoStart: boolean;
      startToTray: boolean;
      minimizeOnClose: boolean;
      language: string;
      autoUpdate: boolean;
      betaUpdates: boolean;
      memoryLimit: number;
      hardwareAcceleration: boolean;
      showTrayIcon: boolean;
      soundEffects: boolean;
    }>
  ): void {
    Object.entries(settings).forEach(([key, value]) => {
      switch (key) {
        case ConfigKey.AUTO_START:
          this.setAutoStart(value as boolean);
          break;
        case ConfigKey.START_TO_TRAY:
          this.setStartToTray(value as boolean);
          break;
        case ConfigKey.CLOSE_TO_TRAY:
          this.setCloseToTray(value as boolean);
          break;
        case ConfigKey.LANGUAGE:
          this.setLanguage(value as string);
          break;
        case ConfigKey.AUTO_UPDATE:
          this.setAutoUpdate(value as boolean);
          break;
        case ConfigKey.BETA_UPDATES:
          this.setBetaUpdates(value as boolean);
          break;
        case ConfigKey.MEMORY_LIMIT:
          this.setMemoryLimit(value as number);
          break;
        case ConfigKey.HARDWARE_ACCELERATION:
          this.setHardwareAcceleration(value as boolean);
          break;
        case ConfigKey.SHOW_TRAY_ICON:
          this.setShowTrayIcon(value as boolean);
          break;
        case ConfigKey.SOUND_EFFECTS:
          this.setSoundEffects(value as boolean);
          break;
      }
    });
  }

  // 兼容旧方法名
  getLaunchToTray(): boolean {
    return this.getAutoStart();
  }

  setLaunchToTray(value: boolean): void {
    log.info(`Setting launchToTray (alias for autoStart) to: ${value}`);
    this.setAutoStart(value);
  }

  getTray(): boolean {
    return this.getShowTrayIcon();
  }

  setTray(value: boolean): void {
    log.info(`Setting tray (alias for showTrayIcon) to: ${value}`);
    this.setShowTrayIcon(value);
  }

  getShortcuts(): Shortcut[] {
    return this.get(ConfigKey.SHORTCUTS);
  }

  setShortcuts(shortcuts: Shortcut[]): void {
    log.info(`Setting shortcuts to: ${JSON.stringify(shortcuts)}`);
    const currentShortcuts = this.get(ConfigKey.SHORTCUTS);
    const filteredShortcuts = shortcuts.filter((shortcut) => shortcut.system);

    // 深度比较数组是否相同
    if (JSON.stringify(currentShortcuts) !== JSON.stringify(filteredShortcuts)) {
      this.set(ConfigKey.SHORTCUTS, filteredShortcuts);
      eventBus.emit('shortcuts:changed', shortcuts);
    }
  }

  getAlwaysOnTop(): boolean {
    return this.get(ConfigKey.ALWAYS_ON_TOP);
  }

  setAlwaysOnTop(value: boolean): void {
    log.info(`Setting alwaysOnTop to: ${value}`);
    const currentValue = this.get(ConfigKey.ALWAYS_ON_TOP);
    if (currentValue !== value) {
      this.set(ConfigKey.ALWAYS_ON_TOP, value);
      eventBus.emit('alwaysOnTop:changed', value);
    }
  }
}

export const config = new Config();
